home *** CD-ROM | disk | FTP | other *** search
- /* Transforms all vertices in the specified polygon-based object into
- view space, then perspective projects them to screen space and maps
- them to screen coordinates, storing the results in the object.
- Recalculates object->view transformation because only if the
- transform changes would we bother to retransform the vertices.
- Also recalculates CenterInView and moves the object through the
- object list accordingly.
- */
- #include <math.h>
- #include "polygon.h"
-
- static Point3 CenterPoint = {0, 0, 0};
-
- void XformAndProjectPObject(PObject * ObjectToXform)
- {
- int i, NumPoints = ObjectToXform->NumVerts;
- Point3 * Points = ObjectToXform->VertexList;
- Point3 * XformedPoints = ObjectToXform->XformedVertexList;
- Point3 * ProjectedPoints =
- ObjectToXform->ProjectedVertexList;
- Point * ScreenPoints = ObjectToXform->ScreenVertexList;
-
- /* Recalculate the object->view transform */
- ConcatXforms(WorldViewXform, ObjectToXform->XformToWorld,
- ObjectToXform->XformToView);
-
- /* Recalculate CenterInView */
- XformVec(ObjectToXform->XformToView, (Fixedpoint *) &CenterPoint,
- (Fixedpoint *) &ObjectToXform->CenterInView);
-
- /* Apply that new transformation and project the points */
- for (i=0; i<NumPoints; i++, Points++, XformedPoints++,
- ProjectedPoints++, ScreenPoints++) {
- /* Transform to view space */
- XformVec(ObjectToXform->XformToView, (Fixedpoint *) Points,
- (Fixedpoint *) XformedPoints);
-
- /* Perspective-project to screen space */
- ProjectedPoints->X =
- FixedMul(FixedDiv(XformedPoints->X, XformedPoints->Z),
- DOUBLE_TO_FIXED(PROJECTION_RATIO * (SCREEN_WIDTH/2)));
- ProjectedPoints->Y =
- FixedMul(FixedDiv(XformedPoints->Y, XformedPoints->Z),
- DOUBLE_TO_FIXED(PROJECTION_RATIO * (SCREEN_WIDTH/2)));
- ProjectedPoints->Z = XformedPoints->Z;
-
- /* Convert to screen coordinates. The Y coord is negated to
- flip from increasing Y being up to increasing Y being down,
- as expected by the polygon filler. Add in half the screen
- width and height to center on the screen */
- ScreenPoints->X = ((int) ((ProjectedPoints->X +
- DOUBLE_TO_FIXED(0.5)) >> 16)) + SCREEN_WIDTH/2;
- ScreenPoints->Y = (-((int) ((ProjectedPoints->Y +
- DOUBLE_TO_FIXED(0.5)) >> 16))) + SCREEN_HEIGHT/2;
- }
- }